﻿Public Class ControlFunctions
  Public Enum Functions As Integer
    ' Null function
    NONE = 0

    ' Playback: Single function buttons
    __PLAYBACK_START = 1
    [Stop] = 1
    Play = 2
    Pause = 3
    PreviousRewind = 5
    NextForward = 6
    SkipBack = 7           ' Argument, number of seconds
    SkipAhead = 8          ' Argument, number of seconds
    MemorizeSong = 9
    OpenAudioFile = 10
    OpenPlaylistFile = 11
    JumpToEntry = 12       ' Argument: which playlist entry in the current list?  1..n (the user won't start counting at 0, so it doesn't make sense for us to, even though internally it's handled this way)
    OpenURL = 13
    'VolUp = 14             ' NOT IN FIRST VERSION: Argument, amount of volume to increase (in percent)
    'VolDown = 15           ' NOT IN FIRST VERSION: Argument, amount of volume to decrease (in percent)
    VolToggle = 16         ' Argument, number of volume 'segments' (plus 1) -- if 4, volume would cycle through 0%, 25%, 50%, 75%, 100%
    'MuteToggle = 17        ' NOT IN FIRST VERSION
    'MonoStereoToggle = 18  ' NOT IN FIRST VERSION
    'ShuffleToggle = 19     ' NOT IN FIRST VERSION
    'ShufflePodcastToggle = 20  ' NOT IN FIRST VERSION
    'RepeatToggle = 21      ' NOT IN FIRST VERSION
    'RepeatPodcastToggle = 22 ' NOT IN FIRST VERSION
    'PreviousTabStop = 23   ' NOT IN FIRST VERSION
    'NextTabStop = 24       ' NOT IN FIRST VERSION
    'AddBookmark = 25       ' NOT IN FIRST VERSION
    'GotoBookmark = 26      ' NOT IN FIRST VERSION: Argument: which bookmark? (in chronological order of the file)
    'PreviousBookmark = 27  ' NOT IN FIRST VERSION
    'NextBookmark = 28      ' NOT IN FIRST VERSION
    Close = 29
    __PLAYBACK_END = 200

    ' General: single function
    __GENERAL_START = 201
    ListUp = 201           ' Move up in the current PrettyList
    ListDown = 202         ' Move Down in the current PrettyList
    ListSelect = 203       ' Select the item on the list
    ListContext = 204      ' TODO: Context menu on the item in the list
    'MenuTabPrevious = 205  ' NOT IN FIRST VERSION: Go to previous menu 'tab' (radio to podcast to music, etc.)
    'MenuTabNext = 206      ' NOT IN FIRST VERSION: Go to next menu 'tab'
    ScenePrevious = 207    ' Go to previous scene in the collection
    SceneNext = 208        ' Go to next scene in the collection
    __GENERAL_END = 400

    ' Multi function buttons
    __MULTI_START = 401
    StopPlayPause = 401
    SelectStopPlayPause = 402  ' Only used for assigned key events, not useful as a button
    __MULTI_END = 600

    ' Sliders
    __SLIDERS_START = 601
    TrackPositionSlider = 601
    'TrackScrubSlider = 602     ' NOT IN FIRST VERSION
    __SLIDERS_END = 800

  End Enum

  Public Shared Function GetControlFunctionIsActive(ByVal func As Functions, ByVal isReady As Boolean, ByVal fileIsLoaded As Boolean, ByVal isWait As Boolean, ByVal isPlaying As Boolean, ByVal isPaused As Boolean, ByVal isStream As Boolean, ByVal playlistCount As Integer) As Boolean
    Return GetControlFunctionIsActive(func, 0, isReady, fileIsLoaded, isWait, isPlaying, isPaused, isStream, playlistCount)
  End Function

  Public Shared Function GetControlFunctionIsActive(ByVal func As Functions, ByVal param As Integer, ByVal isReady As Boolean, ByVal fileIsLoaded As Boolean, ByVal isWait As Boolean, ByVal isPlaying As Boolean, ByVal isPaused As Boolean, ByVal isStream As Boolean, ByVal playlistCount As Integer) As Boolean
    Select Case func
      Case Functions.NextForward, Functions.PreviousRewind
        Return isReady

      Case Functions.Stop, Functions.Close
        Return isReady And fileIsLoaded

      Case Functions.Play
        Return isReady And fileIsLoaded And Not isWait And Not isPlaying

      Case Functions.Pause
        Return isReady And Not isStream And fileIsLoaded And Not isWait And isPlaying

      Case Functions.StopPlayPause
        If isPlaying Then
          If isPaused Then
            Return Not isWait And isReady And fileIsLoaded
          Else ' stop
            If isStream Then
              Return isReady ' Override 'isWait' status because STOP can be used to cancel a stream action
            Else
              Return Not isWait And isReady
            End If
          End If
        ElseIf isStream AndAlso isWait Then
          Return isReady ' Override status because STOP can be used to cancel an action
        Else ' play
          Return Not isWait And isReady And fileIsLoaded
        End If

      Case Functions.SkipAhead, Functions.SkipBack, Functions.TrackPositionSlider
        Return Not isWait And isReady And Not isStream And (isPlaying Or isPaused)

      Case Functions.MemorizeSong
        Return isReady And isStream

      Case Functions.JumpToEntry
        Return param > 0 AndAlso param <= playlistCount ' We don't need 'isready' because these buttons don't care if we are ready for playback controls since they can initiate playback by loading an item directly

      Case Functions.VolToggle, Functions.OpenAudioFile, Functions.OpenPlaylistFile, Functions.OpenURL, Functions.__GENERAL_START To Functions.__GENERAL_END
        Return True

      Case Else
        Return Not isWait And isReady
    End Select
  End Function


  Public Shared Function GetControlFunctionFromMultiFunction(ByVal func As Functions, ByVal isReady As Boolean, ByVal isWait As Boolean, ByVal isPlaying As Boolean, ByVal isPaused As Boolean, ByVal isStream As Boolean, ByVal isListVisible As Boolean) As Functions
    Select Case func
      Case Functions.StopPlayPause
        If isPlaying Then
          If isPaused Then
            ' IS PAUSED; Show play
            Return Functions.Play
          Else
            If isStream Then
              ' IS PLAYING AND IS STREAM; Show stop
              Return Functions.Stop
            Else
              ' IS PLAYING AND IS NOT STREAM; Show pause
              Return Functions.Pause
            End If
          End If
        ElseIf isStream AndAlso isWait Then
          ' STREAM LOADING / REBUFFERING (not ready, but not stopped) so show STOP
          Return Functions.Stop
        Else
          ' IS STOPPED; Show play
          Return Functions.Play
        End If

      Case Functions.SelectStopPlayPause
        If isListVisible Then
          Return Functions.ListSelect
        Else
          Return GetControlFunctionFromMultiFunction(Functions.StopPlayPause, isReady, isWait, isPlaying, isPaused, isStream, isListVisible)
        End If

      Case Else
        Return func ' return the original func if a multi isn't found

    End Select
  End Function


  ''' <summary>
  ''' Some control functions are only available as mapped to events or something.  This tells you whether the control function can be
  ''' used as a UI button.
  ''' </summary>
  Public Shared Function IsControlFunctionAButton(ByVal func As Functions) As Boolean
    Select Case func
      Case Functions.ListUp, Functions.ListDown, Functions.ListSelect, Functions.ListContext, Functions.SelectStopPlayPause, Functions.__GENERAL_END, Functions.__MULTI_END, Functions.__PLAYBACK_END, Functions.__SLIDERS_END
        Return False
    End Select
    Return True
  End Function

  Public Shared Function GetAllValidButtons() As List(Of Integer)
    Static l As List(Of Integer) = Nothing

    If l Is Nothing Then
      l = New List(Of Integer)
      Dim f As Functions
      For Each fi As Reflection.FieldInfo In f.GetType().GetFields(Reflection.BindingFlags.Static Or Reflection.BindingFlags.Public)
        Dim i As Integer = fi.GetValue(f)
        If Not l.Contains(i) AndAlso IsControlFunctionAButton(i) Then
          l.Add(i)
        End If
      Next
    End If

    Return l
  End Function

  ''' <summary>
  ''' Used to determine whether the key repeat capability works for a particular control function
  ''' </summary>
  Public Shared Function IsControlFunctionKeyRepeat(ByVal func As Functions) As Boolean
    Select Case func
      Case Functions.ListUp, Functions.ListDown
        Return True
    End Select
    Return False
  End Function

  Public Shared Function IsControlFunctionWithParamter(ByVal func As Functions) As Boolean
    Select Case func
      Case Functions.SkipAhead, Functions.SkipBack, Functions.JumpToEntry, Functions.VolToggle
        Return True
    End Select
    Return False
  End Function
End Class
